package alp.starcode.nudtportal.framework.util;

import cn.hutool.core.codec.Base64;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;

/**
 * @author : hyc
 * @description :
 * @project : nudt-portal
 * @date : 22022年8月5日09:35:20
 **/
@Slf4j
@Component
public class QRCodeUtils {
    // 二维码尺寸
    private static int QRCODE_SIZE;
    // LOGO宽度
    private static int WIDTH;
    // LOGO高度
    private static int HEIGHT;

    @Value("${qr_code_config.qrcode_size}")
    public void setQrcodeSize(int size) {
        QRCODE_SIZE = size;
    }

    @Value("${qr_code_config.logo_size}")
    public void setLogoSize(int size) {
        HEIGHT = size;
        WIDTH = size;
    }

    /**
     * 生成二维码到指定文件
     *
     * @param filePath
     * @param content
     */
    public void createQRCodeToFile(String filePath, String content) {
        String format = "png";

        HashMap<EncodeHintType, Comparable> hashMap = new HashMap<>();
        hashMap.put(EncodeHintType.CHARACTER_SET, "utf-8"); //指定字符编码为"utf-8
        hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);  //指定二维码的纠错等级为中级
        hashMap.put(EncodeHintType.MARGIN, 5);

        /**
         * 生成二维码
         */
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hashMap);
            makeDirPath(filePath);
            Path file = new File(filePath).toPath();
            MatrixToImageWriter.writeToPath(bitMatrix, format, file);
        } catch (Exception e) {
            log.info("生成二维码失败");
            e.printStackTrace();
        }
    }


    /**
     * 生成二维码,转换为base64的图片格式
     *
     * @param content
     */
    public String createQRCodeToBaseImg(String content) {
        String format = "png";
        String baseStr = null;

        ByteArrayOutputStream os = new ByteArrayOutputStream();

        HashMap<EncodeHintType, Comparable> hashMap = new HashMap<>();
        hashMap.put(EncodeHintType.CHARACTER_SET, "utf-8"); //指定字符编码为"utf-8
        hashMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);  //指定二维码的纠错等级为中级
        hashMap.put(EncodeHintType.MARGIN, 0);

        /**
         * 生成二维码
         */
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hashMap);
//            BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix,new MatrixToImageConfig());
            BufferedImage bufferedImage = new BufferedImage(bitMatrix.getWidth(), bitMatrix.getHeight(), BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < bitMatrix.getWidth(); x++) {
                for (int y = 0; y < bitMatrix.getHeight(); y++) {
                    bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
                }
            }
            //插入logo
//            insertImage(bufferedImage, System.getProperty("user.dir") + File.separator + "images" + File.separator + "logo.png");
            ImageIO.write(bufferedImage, format, os);
            /**
             * 原生转码里面不会有 data:image/png;base64的字段
             */
            baseStr = new String("data:image/png;base64," + Base64.encode(os.toByteArray()));
            return baseStr;
        } catch (Exception e) {
            log.info("生成二维码失败");
            e.printStackTrace();
        }
        return baseStr;
    }


    /**
     * 插入LOGO
     *
     * @param source  二维码图片
     * @param imgPath LOGO图片地址
     * @throws Exception
     */
    private static void insertImage(BufferedImage source, String imgPath) throws Exception {
        //获取画笔
        Graphics2D graphics = source.createGraphics();
        //读取logo图片
        BufferedImage logo = ImageIO.read(new File(imgPath));
        //设置二维码大小，太大了会覆盖二维码，此处为20%
        int logoWidth = WIDTH;
        int logoHeight = HEIGHT;
        //设置logo图片放置的位置，中心
        int x = (source.getWidth() - logoWidth) / 2;
        int y = (source.getHeight() - logoHeight) / 2;
        //开始合并并绘制图片
        graphics.drawImage(logo, x, y, logoWidth, logoHeight, null);
        graphics.drawRoundRect(x, y, logoWidth, logoHeight, 15, 15);
        //logo边框大小
        graphics.setStroke(new BasicStroke(2));
        //logo边框颜色
        graphics.setColor(Color.WHITE);
        graphics.drawRect(x, y, logoWidth, logoHeight);
        graphics.dispose();
        logo.flush();
        source.flush();
    }

    public static void makeDirPath(String targetAddr) {
        File dest = new File(targetAddr);
        if (!dest.exists()) {
            dest.mkdirs();
        }
    }
}
